## Test file to shows the execution speed of the blit function in Matplotlib

import sys
import pylab as p
import numpy as np
import time
import wx

class PlotPanel(wx.Panel):
    def __init__( self, parent, color=None, dpi=80, **kwargs ):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure
        # initialize Panel
        if 'id' not in kwargs.keys():
            kwargs['id'] = wx.ID_ANY
        if 'style' not in kwargs.keys():
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__( self, parent, **kwargs )
        self.SetSize((800,600))

        # initialize matplotlib stuff
        self.figure = Figure( None, dpi )
        self.canvas = FigureCanvasWxAgg( self, -1, self.figure )
        self.SetColor( color )

        self._resizeflag = False

        self.Bind(wx.EVT_IDLE, self._onIdle)
        self.Bind(wx.EVT_SIZE, self._onSize)
        
        self.parent = parent
        
    def SetColor( self, rgbtuple=None ):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ).Get()
        clr = [c/255. for c in rgbtuple]
        self.figure.set_facecolor( clr )
        self.figure.set_edgecolor( clr )
        self.canvas.SetBackgroundColour( wx.Colour( *rgbtuple ) )

    def _onSize( self, event ):
        self._resizeflag = True

    def _onIdle( self, evt ):
        if self._resizeflag:
            self._resizeflag = False
            self._SetSize()

    def _SetSize( self ):
        pixels = self.parent.GetClientSizeTuple()
        self.SetSize( pixels )
        self.canvas.SetSize( pixels )
        self.figure.set_size_inches( float( pixels[0] )/self.figure.get_dpi(),
                                     float( pixels[1] )/self.figure.get_dpi() )
        
class MainApp(wx.App):
    
    def __init__(self):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure
        
        print "init"
        
        app = wx.PySimpleApp()

        self.myframe = wx.Frame(None, -1, size=(800,600))
        self.myframe.Bind(wx.EVT_IDLE, self.update_line)
#        self.plotpanel = PlotPanel(parent=self.myframe, id=-1)
#        
#        self.ax = self.plotpanel.figure.add_subplot(111)
#        self.canvas = self.plotpanel.figure.canvas
        
        self.figure = Figure(None, 80)
        self.canvas = FigureCanvasWxAgg(self.myframe, -1, self.figure)
        self.ax = self.figure.add_subplot(111)
        
        self.myframe.Show()
        
        # for profiling
        self.tstart = time.time()
        
        # create the initial line
        self.x = np.arange(0,2*np.pi,0.01)
        self.line, = self.ax.plot(self.x, np.sin(self.x), animated=True)
        self.canvas.draw()
        # save the clean slate background -- everything but the animated line
        # is drawn and saved in the pixel buffer background
        self.background = self.canvas.copy_from_bbox(self.ax.bbox)
        print self.ax.bbox
        
        self.count = 0
        app.MainLoop()
        return True
        
    def update_line(self, e):
        print "in update_line"
        # restore the clean slate background
        self.canvas.restore_region(self.background)
        # update the data
        self.line.set_ydata(np.sin(self.x+self.count/10.0))
        # just draw the animated artist
        self.ax.draw_artist(self.line)
        # just redraw the axes rectangle
        self.canvas.blit(self.ax.bbox)
    
        if self.count==200:
            # print the timing info and quit
            print 'FPS:' , self.count/(time.time()-self.tstart)
            sys.exit()
    
        self.count += 1
        wx.WakeUpIdle() # ensure that the idle event keeps firing

        return True
        
if __name__ == "__main__":
    MainApp()